home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 076-100 / 093 / dme / command.c next >
C/C++ Source or Header  |  1995-03-13  |  9KB  |  385 lines

  1.  
  2. /*
  3.  * COMMAND.C
  4.  *
  5.  *    (C)Copyright 1987 by Matthew Dillon, All Rights Reserved
  6.  *
  7.  * 'c                single character (typing)
  8.  * `string'          string of characters w/ embedded `' allowed!
  9.  *
  10.  * name arg arg      command name. The arguments are interpreted as strings
  11.  *             for the command.
  12.  *
  13.  * Any string arguments not part of a command are considered to be typed
  14.  * text.
  15.  */
  16.  
  17. #include "defs.h"
  18.  
  19. extern char *breakout();
  20.  
  21. short ComLineMode;
  22. char Abortcommand;
  23.  
  24. typedef struct {
  25.    char *name;      /* command name                    */
  26.    short args;      /* # of arguments                    */
  27.    short sl;      /* 1 if stays within bounds of the current line    */
  28.    int (*func)(); /* function                        */
  29. } COMM;
  30.  
  31. extern int  do_map(),    do_unmap(), do_up(), do_down(), do_left(), do_right(),
  32.         do_return(), do_bs(), do_del(), do_esc(), do_downadd(),
  33.         do_lastcolumn(), do_firstcolumn(), do_edit(), do_tab(),
  34.         do_backtab(), do_save(), do_saveas(), do_deline(), do_insline(),
  35.         do_top(), do_bottom(), do_source(), do_firstnb(),
  36.         do_quit(), do_find(), do_page(), do_savetabs(),
  37.         do_split(), do_goto(), do_screentop(), do_screenbottom(),
  38.         do_join(), do_repeat(), do_tabstop(), do_insertmode(),
  39.         do_block(), do_bdelete(), do_bcopy(), do_bmove(), do_bsave(),
  40.         do_wleft(), do_wright(), do_remeol(), do_savemap(),
  41.         do_toggle(), do_if(), do_tlate(), do_bsource(),
  42.         do_findr(), do_findstr(), do_newwindow(),
  43.         do_windowparm(), do_resize(), do_margin(), do_wordwrap(),
  44.         do_reformat(), do_execute();
  45.  
  46. extern int do_iconify(), do_tomouse();
  47.  
  48.  
  49. /*
  50.  *  WLEFT/WRIGHT will check command line mode themselves, and thus can
  51.  *  be marked sl=1 even though they can change the line number.
  52.  *
  53.  *  No more than 255 commands may exist unless you change the type of hindex[]
  54.  *
  55.  *  Command names MUST be sorted by their first character
  56.  */
  57.  
  58. unsigned char hindex[26];   /*    alpha hash into table    */
  59.  
  60. COMM Comm[] = {
  61.     "back",          0, 1, do_bs,
  62.     "backtab",       0, 1, do_backtab,
  63.     "bcopy",         0, 0, do_bcopy,
  64.     "bdelete",       0, 0, do_bdelete,
  65.     "block",         0, 0, do_block,    /* checks com name for mode */
  66.     "bmove",         0, 0, do_bmove,
  67.     "bottom",        0, 0, do_bottom,
  68.     "bs",            0, 1, do_bs,
  69.     "bsave",         1, 0, do_bsave,
  70.     "bsource",       0, 0, do_bsource,
  71.     "del",           0, 1, do_del,
  72.     "deline",        0, 0, do_deline,
  73.     "down",          0, 0, do_down,
  74.     "downadd",       0, 0, do_downadd,
  75.     "esc",           0, 1, do_esc,
  76.     "escimm",        1, 0, do_esc,
  77.     "execute",       1, 0, do_execute,
  78.     "find",          1, 0, do_find,     /* checks com name for mode */
  79.     "findr",         2, 0, do_findr,    /* checks com name for mode */
  80.     "findstr",       1, 1, do_findstr,  /* checks com name for mode */
  81.     "first",         0, 1, do_firstcolumn,
  82.     "firstnb",       0, 1, do_firstnb,
  83.     "goto",          1, 0, do_goto,
  84.     "height",        1, 1, do_windowparm,
  85.     "iconify",       0, 0, do_iconify,
  86.     "if",            2, 0, do_if,
  87.     "ifelse",        3, 0, do_if,
  88.     "insertmode",    1, 1, do_insertmode,
  89.     "insfile",       1, 0, do_edit,
  90.     "insline",       0, 0, do_insline,
  91.     "join",          0, 0, do_join,
  92.     "last",          0, 1, do_lastcolumn,
  93.     "left",          0, 1, do_left,
  94.     "leftedge",      1, 1, do_windowparm,
  95.     "map",           2, 0, do_map,
  96.     "margin",        1, 1, do_margin,
  97.     "newfile",       1, 0, do_edit,     /* checks com name for mode */
  98.     "newwindow",     0, 0, do_newwindow,
  99.     "next",          0, 0, do_find,
  100.     "nextr",         0, 0, do_findr,
  101.     "pagedown",      0, 0, do_page,
  102.     "pageset",       1, 0, do_page,
  103.     "pageup",        0, 0, do_page,
  104.     "prev",          0, 0, do_find,
  105.     "prevr",         0, 0, do_findr,
  106.     "quit",          0, 0, do_quit,
  107.     "reformat",      0, 0, do_reformat,
  108.     "remeol",        0, 1, do_remeol,
  109.     "repeat",        2, 1, do_repeat,
  110.     "repstr",        1, 1, do_findstr,
  111.     "resettoggle",   1, 1, do_toggle,
  112.     "resize",        2, 0, do_resize,
  113.     "return",        0, 1, do_return,   /* special meaning in command line mode */
  114.     "right",         0, 1, do_right,
  115.     "saveas",        1, 0, do_saveas,
  116.     "savemap",       1, 0, do_savemap,  /* checks com name for mode */
  117.     "saveold",       0, 0, do_save,
  118.     "savesmap",      1, 0, do_savemap,
  119.     "savetabs",      1, 0, do_savetabs,
  120.     "screenbottom",  0, 0, do_screenbottom,
  121.     "screentop",     0, 0, do_screentop,
  122.     "settoggle",     1, 1, do_toggle,
  123.     "source",        1, 0, do_source,
  124.     "split",         0, 0, do_split,
  125.     "tab",           0, 1, do_tab,
  126.     "tabstop",       1, 1, do_tabstop,
  127.     "tlate",         1, 0, do_tlate,
  128.     "toggle",        1, 1, do_toggle,
  129.     "tomouse",       0, 0, do_tomouse,
  130.     "top",           0, 0, do_top,
  131.     "topedge",       1, 1, do_windowparm,
  132.     "unblock",       0, 0, do_block,
  133.     "unmap",         1, 0, do_unmap,
  134.     "up",            0, 0, do_up,
  135.     "while",         2, 0, do_if,
  136.     "width",         1, 1, do_windowparm,
  137.     "wleft",         0, 1, do_wleft,
  138.     "wordwrap",      1, 1, do_wordwrap,
  139.     "wright",        0, 1, do_wright,
  140.     NULL, 0, 0, NULL
  141. };
  142.  
  143. init_command()
  144. {
  145.     register short hi;
  146.     register COMM *comm;
  147.  
  148.  
  149.     hi = sizeof(Comm)/sizeof(Comm[0]) - 2;
  150.     comm = Comm + hi;
  151.  
  152.     while (hi >= 0) {
  153.     hindex[comm->name[0] - 'a'] = hi;
  154.     --hi;
  155.     --comm;
  156.     }
  157. }
  158.  
  159. do_command(str)
  160. char *str;
  161. {
  162.     register char *arg;
  163.     char quoted;
  164.     register short i, j;
  165.     static int level;
  166.  
  167.     if (++level > 20) {
  168.     title("Recursion Too Deep!");
  169.     --level;
  170.     return(0);
  171.     }
  172.     while (arg = breakout(&str, "ed)) {
  173.     if (quoted) {
  174.         text_write(arg);
  175.         continue;
  176.     }
  177.     for (i = 0; arg[i]; ++i) {
  178.         if (arg[i] >= 'A' && arg[i] <= 'Z')
  179.         arg[i] += 'a' - 'A';
  180.     }
  181.     if (arg[0] >= 'a' && arg[0] <= 'z') {
  182.         register COMM *comm = &Comm[hindex[arg[0]-'a']];
  183.         for (; comm->name && comm->name[0] == arg[0]; ++comm) {
  184.         if (strcmp(arg, comm->name) == 0) {
  185.             av[0] = (u_char *)comm->name;
  186.             for (j = 1; j <= comm->args; ++j) {
  187.             av[j] = (u_char *)breakout(&str, "ed);
  188.             if (!av[j]) {
  189.                 title("Bad argument");
  190.                 --level;
  191.                 return(0);
  192.             }
  193.             }
  194.             if (comm->sl || !ComLineMode)
  195.             (*comm->func)(-1);
  196.             if (Abortcommand)
  197.             goto fail;
  198.             goto loop;
  199.         }
  200.         }
  201.     }
  202.     /* Command not found, check for macro    */
  203.  
  204.     {
  205.         char *str;
  206.         int ret;
  207.         str = keyspectomacro(arg);
  208.         if (str) {
  209.         str = (char *)strcpy(malloc(strlen(str)+1), str);
  210.         ret = do_command(str);
  211.         free(str);
  212.         if (ret)
  213.             goto loop;
  214.         goto fail;
  215.         }
  216.     }
  217.  
  218.     title("Unknown Command");
  219. fail:
  220.     --level;
  221.     return(0);
  222. loop:
  223.     ;
  224.     }
  225.     --level;
  226.     return(1);
  227. }
  228.  
  229.  
  230. do_source()
  231. {
  232.     char buf[256];
  233.     long fi;
  234.     register short i;
  235.  
  236.     if (fi = xopen(av[1], "r", 256)) {
  237.     while (xgets(fi, buf, 255)) {
  238.         for (i = 0; buf[i]; ++i) {
  239.         if (buf[i] == 9)
  240.             buf[i] = ' ';
  241.         }
  242.         do_command(buf);
  243.     }
  244.     xclose(fi);
  245.     } else {
  246.     if (av[0])
  247.         title("File not found");
  248.     }
  249. }
  250.  
  251.  
  252. do_quit()
  253. {
  254.     extern char Quitflag;
  255.  
  256.     Quitflag = 1;
  257. }
  258.  
  259. do_execute()
  260. {
  261.     Execute(av[1], 0, 0);
  262. }
  263.  
  264. /*
  265.  * repeat X command
  266.  *
  267.  * Since repeat takes up 512+ stack, it should not be nested more than
  268.  * twice.
  269.  *
  270.  * (if X is not a number it can be abbr. with 2 chars)
  271.  *
  272.  * X =    N     -number of repeats
  273.  *    line  -current line # (lines begin at 1)
  274.  *    lbot  -#lines to the bottom, inc. current
  275.  *    cleft -column # (columns begin at 0)
  276.  *        (thus is also chars to the left)
  277.  *    cright-#chars to eol, including current char
  278.  *    tr    -#char positions to get to next tab stop
  279.  *    tl    -#char positions to get to next backtab stop
  280.  */
  281.  
  282. #define SC(a,b) ((a)<<8|(b))
  283.  
  284. do_repeat()
  285. {
  286.     u_char *ptr = av[1];
  287.     char buf1[256];
  288.     char buf2[256];
  289.     unsigned long n;
  290.  
  291.     breakreset();
  292.     strcpy(buf1, av[2]);
  293.     switch((ptr[0]<<8)+ptr[1]) {
  294.     case SC('l','i'):
  295.     n = text_lineno();
  296.     break;
  297.     case SC('l','b'):
  298.     n = text_lines() - text_lineno() + 1;
  299.     break;
  300.     case SC('c','l'):
  301.     n = text_colno();
  302.     break;
  303.     case SC('c','r'):
  304.     n = text_cols() - text_colno();
  305.     break;
  306.     case SC('t','r'):
  307.     n = text_tabsize()-(text_colno() % text_tabsize());
  308.     break;
  309.     case SC('t','l'):
  310.     n = text_colno() % text_tabsize();
  311.     if (n == 0)
  312.         n = text_tabsize();
  313.     break;
  314.     default:
  315.     n = atoi(av[1]);
  316.     break;
  317.     }
  318.     while (n > 0) {
  319.     strcpy(buf2, buf1);
  320.     if (do_command(buf2) == 0 || breakcheck()) {
  321.         Abortcommand = 1;
  322.         break;
  323.     }
  324.     --n;
  325.     }
  326. }
  327.  
  328.  
  329. char *
  330. breakout(ptr, quoted)
  331. register char **ptr;
  332. char *quoted;
  333. {
  334.     register char *str = *ptr;
  335.     register char *base = str;
  336.  
  337.     *quoted = 0;
  338.     while (*str == ' ')
  339.     ++str;
  340.     if (!*str)
  341.     return(NULL);
  342.     if (*str == '\'') {
  343.     if (str[1]) {
  344.         *quoted = 1;
  345.         base = str + 1;
  346.         if (str[2])
  347.         ++str;
  348.         *str = '\0';
  349.         *ptr = str;
  350.         return(base);
  351.     }
  352.     return(NULL);
  353.     }
  354.     if (*str == '`') {
  355.     short count = 1;
  356.     base = ++str;
  357.     while (*str && count) {
  358.         if (*str == '`')
  359.         ++count;
  360.         if (*str == '\'')
  361.         --count;
  362.         ++str;
  363.     }
  364.     if (count == 0) {
  365.         --str;
  366.         *quoted = 1;
  367.         *str = '\0';
  368.         *ptr = str + 1;
  369.         return(base);
  370.     }
  371.     }
  372.     base = str;
  373.     while (*str && *str != ' ')
  374.     ++str;
  375.     if (*str) {
  376.     *str = '\0';
  377.     *ptr = str + 1;
  378.     return(base);
  379.     }
  380.     *ptr = str;
  381.     return(base);
  382. }
  383.  
  384.  
  385.